/*
 * @Author: wwssaabb
 * @Date: 2021-12-07 15:38:54
 * @LastEditTime: 2021-12-07 17:14:42
 * @FilePath: \handwritten-code\vue\observer2.js
 */


const {
  arrayMethods
} = required('./array2.js')

class Observer {
  constructor(value) {
    //设置ob属性，表示为响应式数据
    Object.defineProperty(value, '__data__', {
      value: this,
      enumerable: false, //
      writeable: true, //
      configurable: true, //
    })

    //数组对象分开处理
    if (Array.isArray(value)) {
      value.__proto__ = arrayMethods
      this.observerArray(value)
    } else {
      this.walk(value)
    }
  }

  observerArray(items) {
    for (let i = 0; i < items.length; i++) observer(items[i])
  }

  walk(data) {
    let keys = Object.keys(data)
    for (let i = 0; i < keys.length; i++) {
      let key = keys[i]
      let value = data[key]
      defineReactive(data, key, value)
    }
  }
}

function defineReactive(data, key, value) {
  Object.defineProperty(data, key, {
    value,
    get() {
      console.log('获取值')
      return value
    },
    set(newValue) {
      if (newValue === value) return
      console.log('设置值')
      value = newValue
    }
  })
}

function observer(value) {
  //如果是对象或数组需要进行响应式处理
  if (typeof value === 'object' && value !== null) return new Observer(value)
}

//代理函数，可以使data里的属性直接用this.xxx来获取，不需要用this.data.xxx
function proxy(vm, source, key) {
  Object.defineProperty(vm, key, {
    get() {
      return vm[source][key]
    },
    set(newVal) {
      return vm[source][key] = newVal
    }
  })
}